/*
 * Project: Set Sample
 * Copyright (C) 2013 alf.labs gmail com,
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.alflabs.setsample.model;

import com.alflabs.annotations.NonNull;
import com.alflabs.serial.SerialReader;
import com.alflabs.serial.SerialWriter;

import java.util.Arrays;
import java.util.Random;

public class SetBoard {
    public static int SX = 4;
    public static int SY = 3;
    public static int SXY = SX * SY;

    public final SetCard mCards[] = new SetCard[SXY];

    public SetBoard() {
        for (int k = 0; k < SXY; k++) {
            mCards[k] = new SetCard();
        }
    }
    public SetCard getCell(int k) {
        return mCards[k];
    }

    /**
     * Randomize the order of the cards, swapping them in-place.
     * @param rnd Random generator, already seeded
     */
    public void randomizeOrder(@NonNull Random rnd) {
        // Low grade implementation: swap 2 random cells, 6-12 times.
        // TODO better randomization later.
        final int N = 6 + rnd.nextInt(6);

        for (int i = 0; i < N; i++) {
            int k1 = rnd.nextInt(SXY);
            int k2 = rnd.nextInt(SXY);
            if (k1 != k2) {
                SetCard c = mCards[k1];
                mCards[k1] = mCards[k2];
                mCards[k2] = c;
            }
        }
    }

    /** Representation for debugging. */
    @Override
    @NonNull
    public String toString() {
        return "<SetBoard " + Arrays.toString(mCards) + '>';
    }

    public SerialWriter toSerial() {
        SerialWriter sw = new SerialWriter();
        sw.addInt("SX", SX);
        sw.addInt("SY", SY);
        for (int i = 0; i < SXY; i++) {
            sw.addInt("_" + i, mCards[i].hashCode());
        }
        return sw;
    }

    public void fromSerial(SerialReader sr) {
        assert SX == sr.getInt("SX");
        assert SY == sr.getInt("SY");
        for (int i = 0; i < SXY; i++) {
            mCards[i].set(new SetCard(sr.getInt("_" + i)));
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        SetBoard setBoard = (SetBoard) o;
        return Arrays.equals(mCards, setBoard.mCards);
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(mCards);
    }
}
